import {Cask} from 'cascadium';

export const convertDate = (dateString) => {
  return new Date(Math.round((dateString - 25569)*86400*1000));
}

export const balanceCols = (type) => {
  const 中 = {
    opening: '初',
    closing: '末',
  }[type]
  return [
    [`期${中}　　　　`, type],
    [`期${中}数　　　`, type],
    [`账面期${中}数　`, type],
    [`账面期${中}余额`, type],
    [`期${中}金额　　`, type],
    [`期${中}余额借方`, `${type}_dr`],
    [`期${中}余额贷方`, `${type}_cr`],
  ]
}

export const accrualCols = (type) => {

  const 中 = {
    dr: '借',
    cr: '贷'
  }[type]

  return [
    [`${中}方　　　　　`, type],
    [`本期${中}方　　　`, type],
    [`${中}方发生　　　`, type],
    [`${中}方发生额　　`, type],
    [`本期发生${中}方　`, type],
    [`未审${中}方发生额`, type],
    [`账面${中}方发生额`, type],
  ]
}


const columnMap = [

  ['iyear', 'year'],
  ['会计年', 'year'],
  ['年份　', 'year'],
  
  ['isignseq', 'voucherType'],
  ['凭证类型编号', 'voucherType'],
  ['凭证类别排序', 'voucherType'],

  ['iperiod', 'month'],
  ['会计期间', 'month'],
  ['会计月', 'month'],
  ['月份　', 'month'],  

  ['dbill_date', 'billDate'],
  ['记账时间', 'billDate', convertDate],

  ['code', 'code'],
  ['ccode', 'code'],
  ['科目编号', 'code'],
  ['科目编码', 'code'],

  ['name', 'name'],
  ['ccode_name', 'name'],
  ['科目名称', 'name'],

  ['cclass', 'categoryType'],
  ['科目类别', 'categoryType'],

  ...balanceCols('opening'),
  ...accrualCols('dr'),
  ...accrualCols('cr'),
  ...balanceCols('closing'),

  ['md', 'dr'],
  ['mc', 'cr'],

  ['ino_id', 'voucherID'],
  ['凭证编号', 'voucherID'],
  ['凭证号　', 'voucherID'],

  ['inid', 'lineID'],
  ['编号　', 'lineID'],
  ['行号　', 'lineID'],
  ['凭证行', 'lineID'],
  ['凭证行号', 'lineID'],

  ['cdigest', 'desc'],
  ['摘要　　　', 'desc'],
  ['业务说明　', 'desc'],

  ['核算项目', 'itemName'],
  ['核算项目名称', 'itemName'],
  
  ['核算项目ID', 'itemCode'],
  ['核算项目编号', 'itemCode'],

  ['核算项目类型名称', 'itemTypeName'],
  ['核算项目类型编号', 'itemTypeCode'],
]

const handleNum = (orig) => {
  if (orig === undefined) {
    return 0;
  } else if (typeof orig === 'string' && orig[0] !== '=') {
    return parseFloat(orig.replace(/[\s,]/g, ''));
  } else {
    return orig;
  }
}

const handleDir = (orig) => {
  return {
    Dr: 'dr',
    Cr: 'cr',
    借: 'dr',
    贷: 'cr',
  }[orig]
}

const handleRec = (rec) => {
  const {code, name, opening, cr, dr, closing, direction, amount} = rec;
  const handled = {
    code: code && code.toString(),
    name: name && name.toString().split('\\').pop(),
    opening: handleNum(opening),
    closing: handleNum(closing),
    direction: handleDir(direction),
    dr: handleNum(dr),
    cr: handleNum(cr),
    amount: handleNum(amount),
  }

  return Object.assign(rec, handled);
}

const mapEntry = (origRec, map, {eliminating=true} ={}) => {

  let entries = Object.entries(origRec);
  if (eliminating) {
    entries = entries.filter(([k]) => map[k]);
  }
  entries = entries.map(([k, v]) => {
    const {key, func=e=>e} = map[k];
    return [key, func(v)];
  });
  
  return Object.fromEntries(entries);
}

function marshallColumn(origData, {EntryCons=Balance}={}){

  const cookedMap = {};
  for (let [origKey, key, func] of columnMap) {
    cookedMap[origKey.trim()] = {key, func};
  }

  const currData = new Cask();
  for (let {style, ...entry} of origData) {
    const entryInstance = new EntryCons(handleRec(mapEntry(entry, cookedMap)));
    entryInstance.attr.style = style;
    currData.push(entryInstance);
  }

  return currData;
}

export default marshallColumn;